home *** CD-ROM | disk | FTP | other *** search
/ Aminet 23 / Aminet 23 (1998)(GTI - Schatztruhe)[!][Feb 1998].iso / Aminet / misc / emu / amiSPIMsrc.lha / xspim.c < prev    next >
C/C++ Source or Header  |  1994-01-17  |  43KB  |  1,730 lines

  1. /* SPIM S20 MIPS simulator.
  2.    X interface to SPIM
  3.    (Derived from an earlier work by Alan Siow.)
  4.    Copyright (C) 1990-1994 by James Larus (larus@cs.wisc.edu).
  5.    ALL RIGHTS RESERVED.
  6.  
  7.    SPIM is distributed under the following conditions:
  8.  
  9.      You may make copies of SPIM for your own use and modify those copies.
  10.  
  11.      All copies of SPIM must retain my name and copyright notice.
  12.  
  13.      You may not sell SPIM or distributed SPIM in conjunction with a
  14.      commerical product or service without the expressed written consent of
  15.      James Larus.
  16.  
  17.    THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  18.    IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  19.    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  20.    PURPOSE. */
  21.  
  22.  
  23. /* $Header: /home/primost/larus/Software/SPIM/RCS/xspim.c,v 3.74 1994/01/18 03:21:45 larus Exp larus $
  24.  */
  25.  
  26. #include <stdio.h>
  27. #include <setjmp.h>
  28. #ifdef __STDC__
  29. #include <stdarg.h>
  30. #else
  31. #include <varargs.h>
  32. #endif
  33.  
  34. #include <X11/Intrinsic.h>
  35. #include <X11/StringDefs.h>
  36. #include <X11/Shell.h>
  37. #include <X11/Xlib.h>
  38. #include <X11/Xaw/Cardinals.h>
  39. #include <X11/Xaw/Paned.h>
  40. #include <X11/Xaw/AsciiText.h>
  41. #include <X11/Xaw/Text.h>
  42. #include <X11/Xaw/Dialog.h>
  43. #include <X11/keysym.h>
  44.  
  45. #include "spim.h"
  46. #include "spim-utils.h"
  47. #include "inst.h"
  48. #include "mem.h"
  49. #include "reg.h"
  50. #include "y.tab.h"
  51. #include "buttons.h"
  52. #include "windows.h"
  53. #include "read-aout.h"
  54. #include "xspim.h"
  55.  
  56. #ifdef CL_SPIM
  57. #include "cl-cache.h"
  58. #include "cl-except.h"
  59. #include "cl-tlb.h"
  60. #include "cl-cycle.h"
  61. #endif
  62.  
  63.  
  64. typedef struct _AppResources
  65. {
  66.   String textFont;
  67.   Boolean bare;
  68.   Boolean asmm;
  69.   Boolean trap;
  70.   Boolean quiet;
  71.   Boolean mapped_io;
  72. #ifdef CL_SPIM
  73.   Boolean cycle;
  74.   Boolean icache;
  75.   Boolean dcache;
  76.   Boolean tlb;
  77. #endif
  78.   char *filename;
  79.   char *ex_filename;
  80.   char *display2;
  81.   Boolean hex_gpr;
  82.   Boolean hex_fpr;
  83.   char *initial_data_limit;
  84.   char *initial_data_size;
  85.   char *initial_k_data_limit;
  86.   char *initial_k_data_size;
  87.   char *initial_k_text_size;
  88.   char *initial_stack_limit;
  89.   char *initial_stack_size;
  90.   char *initial_text_size;
  91. } AppResources;
  92.  
  93.  
  94. /* Exported variables: */
  95.  
  96. /* Not local, but not export so all files don't need setjmp.h */
  97. jmp_buf spim_top_level_env; /* For ^C */
  98. reg_word R[32];
  99. reg_word HI, LO;
  100. int HI_present, LO_present;
  101. mem_addr PC, nPC;
  102. double *FPR;            /* Dynamically allocate so overlay */
  103. float *FGR;            /* is possible */
  104. int *FWR;            /* is possible */
  105. int FP_reg_present;        /* Presence bits for FP registers */
  106. int FP_reg_poison;        /* Poison bits for FP registers */
  107. int FP_spec_load;        /* Is register waiting for a speculative ld */
  108. reg_word CpCond[4], CCR[4][32], CPR[4][32];
  109.  
  110. int bare_machine;        /* Simulate bare instruction set */
  111. int quiet;            /* No warning messages */
  112. int source_file;        /* Program is source, not binary */
  113. int message_out, console_out, console_in;
  114. int mapped_io;            /* Non-zero => activate memory-mapped IO */
  115. int pipe_out;
  116. int cycle_level;        /* non-zero => cycle level mode */
  117. mem_addr program_starting_address;
  118. long initial_text_size;
  119. long initial_data_size;
  120. long initial_data_limit;
  121. long initial_stack_size;
  122. long initial_stack_limit;
  123. long initial_k_text_size;
  124. long initial_k_data_size;
  125. long initial_k_data_limit;
  126.  
  127. XtAppContext app_con;
  128. Widget message, console;
  129. #ifdef CL_SPIM
  130. Widget pipeline;
  131. #endif
  132. XtAppContext app_context;
  133. XFontStruct *text_font;
  134. Dimension button_width;
  135. int load_trap_handler;
  136. Pixmap mark;
  137.  
  138.  
  139. /* Local functions: */
  140.  
  141. #ifdef __STDC__
  142. static void center_text_at_PC (void);
  143. static char *check_buf_limit (char *, int *, int *);
  144. static void display_data_seg (void);
  145. static char *display_values (mem_addr from, mem_addr to, char *buf, int *limit,
  146.                  int *n);
  147. static char *display_insts (mem_addr from, mem_addr to, char *buf, int *limit,
  148.                 int *n);
  149. static void display_registers (void);
  150. static void initialize (AppResources app_res);
  151. static mem_addr print_partial_line (mem_addr, char *, int *, int *);
  152. static void show_running (void);
  153. static void syntax (char *program_name);
  154. static void write_text_to_window (Widget w, char *s);
  155.  
  156. #ifdef CL_SPIM
  157. static void display_pipeline (void);
  158. static void display_cache (Widget stats, Widget data, int type);
  159. #endif
  160.  
  161. #else
  162. static void center_text_at_PC ();
  163. static char *check_buf_limit ();
  164. static void display_data_seg ();
  165. static char *display_values ();
  166. static char *display_insts ();
  167. static void display_registers ();
  168. static void initialize ();
  169. static mem_addr print_partial_line ();
  170. static void show_running ();
  171. static void syntax ();
  172. static void write_text_to_window ();
  173.  
  174. #ifdef CL_SPIM
  175. static void display_pipeline ();
  176. static void display_cache ();
  177. #endif
  178. #endif
  179.  
  180. static String fallback_resources[] =
  181. {
  182.   "*font:        *-courier-medium-r-normal--12-*-75-*",
  183.   "*Label*font:        *-adobe-helvetica-bold-r-*-*-12-*-75-*",
  184.   "*panel*font:        *-adobe-helvetica-medium-r-*-*-12-*-75-*",
  185.   "*ShapeStyle:        Oval",
  186.   "*dialog*value.translations: #override \\n <Key>Return: confirm()",
  187.   "*.translations: #override \\n <Ctrl>C: control_c_seen()",
  188.   "*Form*left:        ChainLeft",
  189.   "*Form*right:        ChainLeft",
  190.   "*Form*top:        ChainTop",
  191.   "*Form*bottom:    ChainTop",
  192.   "*console.label:    SPIM Console",
  193.   "*Shell1*iconName:    SPIM Console",
  194. #ifdef CL_SPIM
  195.   "*terminal3.label:    SPIM Pipeline",
  196.   "*Shell3*iconName:    SPIM Pipeline",
  197.   "*terminal4.label:    SPIM Data Cache",
  198.   "*Shell4*iconName:    SPIM Data Cache",
  199.   "*terminal5.label:    SPIM Inst Cache",
  200.   "*Shell5*iconName:    SPIM Inst Cache",
  201. #endif
  202.   NULL,
  203. };
  204.  
  205.  
  206. static XtActionsRec actionTable[2] =
  207. {
  208.   {"confirm", (XtActionProc) confirm},
  209.   {"control_c_seen", (XtActionProc) control_c_seen},
  210. };
  211.  
  212.  
  213. static XtResource resources[23] =
  214. {
  215.   {XtNfont, XtCFont, XtRString, sizeof (char *),
  216.      XtOffset (AppResources *, textFont), XtRString, NULL},
  217.   {"bare", "Bare", XtRBoolean, sizeof (Boolean),
  218.      XtOffset (AppResources *, bare), XtRImmediate, False},
  219.   {"asm",  "Asm",  XtRBoolean, sizeof (Boolean),
  220.      XtOffset (AppResources *, asmm), XtRImmediate, False},
  221.   {"trap", "Trap", XtRBoolean, sizeof (Boolean),
  222.      XtOffset (AppResources *, trap), XtRImmediate, (XtPointer) True},
  223.   {"quiet", "Quiet", XtRBoolean, sizeof (Boolean),
  224.      XtOffset (AppResources *, quiet), XtRImmediate, False},
  225.   {"mapped_io", "Mapped_IO", XtRBoolean, sizeof (Boolean),
  226.      XtOffset (AppResources *, mapped_io), XtRImmediate, False},
  227.  
  228. #ifdef CL_SPIM
  229.   {"cycle", "Cycle", XtRBoolean, sizeof (Boolean),
  230.      XtOffset (AppResources *, cycle), XtRImmediate, False},
  231.   {"dcache", "DataCache", XtRBoolean, sizeof (Boolean),
  232.      XtOffset (AppResources *, dcache), XtRImmediate, False},
  233.   {"icache", "InstCache", XtRBoolean, sizeof (Boolean),
  234.      XtOffset (AppResources *, icache), XtRImmediate, False},
  235.   {"tlb", "TLB", XtRBoolean, sizeof (Boolean),
  236.      XtOffset (AppResources *, tlb), XtRImmediate, False},
  237. #endif
  238.  
  239.   {"filename", "Filename", XtRString, sizeof (char *),
  240.      XtOffset (AppResources *, filename), XtRString, NULL},
  241.   {"ex_filename", "Ex_Filename", XtRString, sizeof (char *),
  242.      XtOffset (AppResources *, ex_filename), XtRString, NULL},
  243.   {"display2", "Display2", XtRString, sizeof (char *),
  244.      XtOffset (AppResources *, display2), XtRString, NULL},
  245.   {"hexGpr", "DisplayHex", XtRBoolean, sizeof (Boolean),
  246.      XtOffset (AppResources *, hex_gpr), XtRImmediate, (XtPointer) True},
  247.   {"hexFpr", "DisplayHex", XtRBoolean, sizeof (Boolean),
  248.      XtOffset (AppResources *, hex_fpr), XtRImmediate, False},
  249.  
  250.   {"stext", "Stext", XtRString, sizeof (char *),
  251.      XtOffset (AppResources *, initial_text_size), XtRString, NULL},
  252.   {"sdata", "Sdata", XtRString, sizeof (char *),
  253.      XtOffset (AppResources *, initial_data_size), XtRString, NULL},
  254.   {"ldata", "Ldata", XtRString, sizeof (char *),
  255.      XtOffset (AppResources *, initial_data_limit), XtRString, NULL},
  256.   {"sstack", "Sstack", XtRString, sizeof (char *),
  257.      XtOffset (AppResources *, initial_stack_size), XtRString, NULL},
  258.   {"lstack", "Lstack", XtRString, sizeof (char *),
  259.      XtOffset (AppResources *, initial_stack_limit), XtRString, NULL},
  260.   {"sktext", "Sktext", XtRString, sizeof (char *),
  261.      XtOffset (AppResources *, initial_k_text_size), XtRString, NULL},
  262.   {"skdata", "Skdata", XtRString, sizeof (char *),
  263.      XtOffset (AppResources *, initial_k_data_size), XtRString, NULL},
  264.   {"lkdata", "Lkdata", XtRString, sizeof (char *),
  265.      XtOffset (AppResources *, initial_k_data_limit), XtRString, NULL}
  266. };
  267.  
  268.  
  269. static XrmOptionDescRec options[] =
  270. {
  271.   {"-bare",   "bare", XrmoptionNoArg, "True"},
  272.   {"-asm",    "asmm",  XrmoptionNoArg, "True"},
  273.   {"-trap",   "trap", XrmoptionNoArg, "True"},
  274.   {"-notrap", "trap", XrmoptionNoArg, "False"},
  275.   {"-quiet",  "quiet", XrmoptionNoArg, "True"},
  276.   {"-noquiet","quiet", XrmoptionNoArg, "False"},
  277.   {"-mapped_io",  "mapped_io", XrmoptionNoArg, "True"},
  278.   {"-nomapped_io","mapped_io", XrmoptionNoArg, "False"},
  279.  
  280. #ifdef CL_SPIM
  281.   {"-cycle",  "cycle", XrmoptionNoArg, "True"},
  282.   {"-dcache", "dcache", XrmoptionNoArg, "True"},
  283.   {"-nodcache", "dcache", XrmoptionNoArg, "False"},
  284.   {"-icache", "icache", XrmoptionNoArg, "True"},
  285.   {"-noicache", "icache", XrmoptionNoArg, "False"},
  286.   {"-tlb",    "tlb", XrmoptionNoArg, "True"},
  287.   {"-notlb",  "tlb", XrmoptionNoArg, "False"},
  288. #endif
  289.  
  290.   {"-file",   "filename", XrmoptionSepArg, NULL},
  291.   {"-execute","ex_filename", XrmoptionSepArg, NULL},
  292.   {"-d2",     "display2", XrmoptionSepArg, NULL},
  293.   {"-hexgpr", "hexGpr", XrmoptionNoArg, "True"},
  294.   {"-nohexgpr", "hexGpr", XrmoptionNoArg, "False"},
  295.   {"-hexfpr", "hexFpr", XrmoptionNoArg, "True"},
  296.   {"-nohexfpr", "hexFpr", XrmoptionNoArg, "False"},
  297.   {"-stext", "stext", XrmoptionSepArg, NULL},
  298.   {"-sdata", "sdata", XrmoptionSepArg, NULL},
  299.   {"-ldata", "ldata", XrmoptionSepArg, NULL},
  300.   {"-sstack", "sstack", XrmoptionSepArg, NULL},
  301.   {"-lstack", "lstack", XrmoptionSepArg, NULL},
  302.   {"-sktext", "sktext", XrmoptionSepArg, NULL},
  303.   {"-skdata", "skdata", XrmoptionSepArg, NULL},
  304.   {"-lkdata", "lkdata", XrmoptionSepArg, NULL}
  305. };
  306.  
  307.  
  308. #define TICK_WIDTH 10
  309.  
  310. #define TICK_HEIGHT 10
  311.  
  312. static char tick_bits[] = {
  313.   0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x80, 0x01, 0xc1, 0x00, 0x63, 0x00,
  314.   0x36, 0x00, 0x1c, 0x00, 0x08, 0x00, 0x00, 0x00};
  315.  
  316.  
  317. /* Flags to control the way that registers are displayed. */
  318.  
  319. static int print_gpr_hex;        /* Print GPRs in hex/decimal */
  320. static int print_fpr_hex;        /* Print FPRs in hex/floating point */
  321.  
  322.  
  323. /* Local variables: */
  324.  
  325. static Dimension app_width;
  326. static Dimension button_height;
  327. static Dimension command_height;
  328. static Dimension command_hspace;
  329. static Dimension command_vspace;
  330. static int console_is_visible;
  331. static Dimension display_height;
  332. static char *ex_file_name = NULL;
  333. static char *file_name = NULL;
  334. static Dimension reg_min_height;
  335. static Dimension reg_max_height;
  336. static Dimension segment_height;
  337. static Widget shell1;
  338. static int spim_is_running = 0;
  339. static Widget toplevel;
  340.  
  341. #ifdef CL_SPIM
  342. static Widget shell3;
  343. static Widget toplevel_cache;
  344. static Widget dcache_stats, icache_stats, dcache_data, icache_data;
  345. static int pipeline_is_visible;
  346. static int dcache_is_visible;
  347. static int icache_is_visible;
  348. #endif
  349.  
  350.  
  351.  
  352. #ifdef __STDC__
  353. static void
  354. initialize (AppResources app_res)
  355. #else
  356. static void
  357. initialize (app_res)
  358.      AppResources app_res;
  359. #endif
  360. {
  361.   if (app_res.bare)
  362.     bare_machine = 1;
  363.   if (app_res.asmm)
  364.     bare_machine = 0;
  365.   if (app_res.trap)
  366.     load_trap_handler = 1;
  367.   else
  368.     load_trap_handler = 0;
  369.  
  370.   if (app_res.quiet)
  371.     quiet = 1;
  372.   else
  373.     quiet = 0;
  374.  
  375.   if (app_res.mapped_io)
  376.     mapped_io = 1;
  377.   else
  378.     mapped_io = 0;
  379.  
  380. #ifdef CL_SPIM
  381.   if (app_res.cycle)
  382.     {
  383.       cycle_level = 1;
  384.       bare_machine = 1;
  385.       load_trap_handler = 0;
  386.     }
  387.   else
  388.     cycle_level = 0;
  389.   if (app_res.dcache)
  390.     dcache_on = 1;
  391.   else
  392.     dcache_on = 0;
  393.   if (app_res.icache)
  394.     icache_on = 1;
  395.   else
  396.     icache_on = 0;
  397.   if (app_res.tlb)
  398.     tlb_on = 1;
  399.   else
  400.     tlb_on = 0;
  401. #endif
  402.  
  403.   if (app_res.filename)
  404.     file_name = app_res.filename;
  405.   if (app_res.ex_filename)
  406.     {
  407.       ex_file_name = app_res.ex_filename;
  408.       load_trap_handler = 0;
  409.     }
  410.  
  411.   if (app_res.textFont == NULL)
  412.     app_res.textFont = XtNewString ("8x13");
  413.   if (!(text_font = XLoadQueryFont (XtDisplay (toplevel), app_res.textFont)))
  414.     fatal_error ("Cannot open font %s\n", app_res.textFont);
  415.  
  416.   mark = XCreateBitmapFromData (XtDisplay (toplevel),
  417.                 RootWindowOfScreen (XtScreen (toplevel)),
  418.                 tick_bits, TICK_WIDTH, TICK_HEIGHT);
  419.  
  420.   button_height = TEXTHEIGHT * 1.6;
  421.   button_width = TEXTWIDTH * 12;
  422.   app_width = 6 * (button_width + 16);
  423.   if (app_width < TEXTWIDTH * 4 * 22) /* Register display width */
  424.     app_width = TEXTWIDTH * 4 * 22;
  425.   command_hspace = 8;
  426.   command_vspace = 8;
  427. #ifndef CL_SPIM
  428.   command_height = (button_height * 2) + (command_vspace * 3) + 2;
  429. #else
  430.   command_height = (button_height * 3) + (command_vspace * 4) + 2;
  431. #endif
  432.   reg_min_height = 19 * TEXTHEIGHT + 4;
  433.   reg_max_height = reg_min_height + 8 * TEXTHEIGHT + 4;
  434.   segment_height = 10 * TEXTHEIGHT + 4;
  435.   display_height = 8 * TEXTHEIGHT + 4;
  436.   print_gpr_hex = app_res.hex_gpr;
  437.   print_fpr_hex = app_res.hex_fpr;
  438. }
  439.  
  440.  
  441. #ifdef __STDC__
  442. int
  443. main (int argc, char **argv)
  444. #else
  445. int
  446. main (argc, argv)
  447.      int argc;
  448.      char **argv;
  449. #endif
  450. {
  451.   Widget toplevel2, pane1;
  452. #ifdef CL_SPIM
  453.   Widget toplevel3, pane3;
  454. #endif
  455.   AppResources app_res;
  456.   Display *display;
  457.   Arg args[10];
  458.   Cardinal n;
  459.  
  460.   toplevel = XtAppInitialize (&app_context, "Xspim", options,
  461.                   XtNumber (options), &argc, argv,
  462.                   fallback_resources, NULL, ZERO);
  463.  
  464.   if (argc != 1)
  465.     syntax (argv[0]);
  466.  
  467.   XtGetApplicationResources (toplevel, (XtPointer) &app_res, resources,
  468.                  XtNumber (resources), NULL, ZERO);
  469.  
  470.   if (app_res.display2 == NULL)
  471.     display = XtDisplay (toplevel);
  472.   else
  473.     display = XtOpenDisplay (app_context, app_res.display2, "xspim",
  474.                  "Xspim", NULL, ZERO, &argc, argv);
  475.  
  476.   toplevel2 = XtAppCreateShell ("xspim","Xspim",applicationShellWidgetClass,
  477.                 display, NULL, ZERO);
  478.  
  479. #ifdef CL_SPIM
  480.   toplevel3 = XtAppCreateShell ("xspim","Xspim",applicationShellWidgetClass,
  481.                 display, NULL, ZERO);
  482.   toplevel_cache = XtAppCreateShell ("xspim","Xspim",
  483.                      applicationShellWidgetClass, display,
  484.                      NULL, ZERO);
  485. #endif
  486.  
  487.   XtAppAddActions (app_context, actionTable, XtNumber (actionTable));
  488.  
  489.   initialize (app_res);
  490.  
  491.   /* Console window */
  492.  
  493.   shell1 = XtCreatePopupShell ("Shell1", topLevelShellWidgetClass,
  494.                    toplevel, NULL, ZERO);
  495.   pane1 = XtCreateManagedWidget ("pane1", panedWidgetClass, shell1,
  496.                  NULL, ZERO);
  497.   n = 0;
  498.   XtSetArg (args[n], XtNeditType, XawtextAppend); n++;
  499.   XtSetArg (args[n], XtNscrollVertical, XawtextScrollWhenNeeded); n++;
  500.   XtSetArg (args[n], XtNpreferredPaneSize, TEXTHEIGHT * 24); n++;
  501.   XtSetArg (args[n], XtNwidth, TEXTWIDTH * 80); n++;
  502.   console = XtCreateManagedWidget ("console", asciiTextWidgetClass, pane1,
  503.                    args, n);
  504.   XawTextEnableRedisplay (console);
  505.   console_out = (int) console;
  506.  
  507. #ifdef CL_SPIM
  508.   /* Pipeline window */
  509.  
  510.   shell3 = XtCreatePopupShell ("Shell3", topLevelShellWidgetClass,
  511.                    toplevel3, NULL, ZERO);
  512.   pane3 = XtCreateManagedWidget ("pane3", panedWidgetClass, shell3,
  513.                  NULL, ZERO);
  514.   n = 0;
  515.   XtSetArg (args[n], XtNtype, XawAsciiString); n++;
  516.   XtSetArg (args[n], XtNeditType, XawtextRead); n++;
  517.   XtSetArg (args[n], XtNpreferredPaneSize, TEXTHEIGHT * 20); n++;
  518.   XtSetArg (args[n], XtNwidth, TEXTWIDTH * 70); n++;
  519.   XtSetArg (args[n], XtNstring, ""); n++;
  520.   XtSetArg (args[n], XtNborderWidth, 0); n++;
  521.   XtSetArg (args[n], XtNdisplayCaret, False); n++;
  522.   pipeline = XtCreateManagedWidget ("pipeline", asciiTextWidgetClass, pane3,
  523.                     args, n);
  524. #endif
  525.  
  526.   create_sub_windows (toplevel, app_width, reg_min_height, reg_max_height,
  527.               command_height, command_hspace, command_vspace,
  528.               button_height, segment_height, display_height);
  529.  
  530.   XtRealizeWidget (toplevel);
  531.  
  532.   if (app_res.initial_text_size != NULL)
  533.     initial_text_size = atoi (app_res.initial_text_size);
  534.   if (app_res.initial_data_size != NULL)
  535.     initial_data_size = atoi (app_res.initial_data_size);
  536.   if (app_res.initial_data_limit != NULL)
  537.     initial_data_limit = atoi (app_res.initial_data_limit);
  538.   if (app_res.initial_stack_size != NULL)
  539.     initial_stack_size = atoi (app_res.initial_stack_size);
  540.   if (app_res.initial_stack_limit != NULL)
  541.     initial_stack_limit = atoi (app_res.initial_stack_limit);
  542.   if (app_res.initial_k_text_size != NULL)
  543.     initial_k_text_size = atoi (app_res.initial_k_text_size);
  544.   if (app_res.initial_k_data_size != NULL)
  545.     initial_k_data_size = atoi (app_res.initial_k_data_size);
  546.   if (app_res.initial_k_data_limit != NULL)
  547.     initial_k_data_limit = atoi (app_res.initial_k_data_limit);
  548.   write_startup_message ();
  549.   initialize_world (load_trap_handler);
  550. #ifdef CL_SPIM
  551.   cl_initialize_world (0);
  552. #endif
  553.  
  554.   if (file_name)
  555.     {
  556.       read_file (file_name, 1);
  557.       record_file_name_for_prompt (file_name);
  558.     }
  559.   else if (ex_file_name)
  560.     {
  561.       initialize_world (0);    /* Don't have a trap handler loaded. */
  562. #ifdef CL_SPIM
  563.       cl_initialize_world (0);
  564. #endif
  565.       read_file (ex_file_name, 0);
  566.       record_file_name_for_prompt (ex_file_name);
  567.     }
  568.   else
  569.     {
  570.       redisplay_text ();
  571.       redisplay_data ();
  572.     }
  573.  
  574.   XtAppMainLoop (app_context);
  575.   return (0);
  576. }
  577.  
  578.  
  579. #ifdef __STDC__
  580. static void
  581. syntax (char *program_name)
  582. #else
  583. static void
  584. syntax (program_name)
  585.      char *program_name;
  586. #endif
  587. {
  588.   XtDestroyApplicationContext (app_context);
  589.   fprintf (stderr, "Usage:\n %s", program_name);
  590.   fprintf (stderr, "\t[ -bare/-asm ] [ -trap/-notrap ] [ -quiet/noquiet ]\n");
  591.   fprintf (stderr, "\t[ -mapped_io/-nomapped_io ]\n");
  592.   fprintf (stderr, "\t[ -d2 <display> ] [ -file/-execute <filename> ]\n");
  593.   fprintf (stderr, "\t[ -s<seg> <size>] [ -l<seg> <size>]\n");
  594.   exit (1);
  595. }
  596.  
  597.  
  598. #ifdef __STDC__
  599. void
  600. control_c_seen (int arg)
  601. #else
  602. void
  603. control_c_seen (arg)
  604. int arg;
  605. #endif
  606. {
  607.   write_output (message_out, "\nExecution interrupted\n");
  608.   redisplay_data ();
  609.   continue_prompt (1);
  610.   if (spim_is_running)
  611.     longjmp (spim_top_level_env, 1);
  612. }
  613.  
  614.  
  615. #ifdef __STDC__
  616. void
  617. popup_console (Widget w, XtPointer client_data, XtPointer call_data)
  618. #else
  619. void
  620. popup_console (w, client_data, call_data)
  621.      Widget w;
  622.      XtPointer client_data, call_data;
  623. #endif
  624. {
  625.   if (console_is_visible)
  626.     {
  627.       console_is_visible = 0;
  628.       XtPopdown (shell1);
  629.     }
  630.   else
  631.     {
  632.       console_is_visible = 1;
  633.       XtPopup (shell1, XtGrabNone);
  634.     }
  635. }
  636.  
  637.  
  638. #ifdef CL_SPIM
  639. #ifdef __STDC__
  640. void
  641. popup_pipeline (Widget w, XtPointer client_data, XtPointer call_data)
  642. #else
  643. void
  644. popup_pipeline (w, client_data, call_data)
  645.      Widget w;
  646.      XtPointer client_data, call_data;
  647. #endif
  648. {
  649.   if (pipeline_is_visible)
  650.     {
  651.       pipeline_is_visible = 0;
  652.       XtPopdown (shell3);
  653.     }
  654.   else
  655.     {
  656.       pipeline_is_visible = 1;
  657.       XtPopup (shell3, XtGrabNone);
  658.       display_pipeline ();
  659.     }
  660. }
  661.  
  662.  
  663. #ifdef __STDC__
  664. void
  665. pop_dcache (Widget w, XtPointer client_data, XtPointer call_data)
  666. #else
  667. void
  668. pop_dcache (w, client_data, call_data)
  669.      Widget w;
  670.      XtPointer client_data, call_data;
  671. #endif
  672. {
  673.   static Widget shell = NULL;
  674.   Widget pane;
  675.   Arg args[10];
  676.   int n;
  677.  
  678.   if (dcache_is_visible)
  679.     {
  680.       dcache_is_visible = 0;
  681.       XtDestroyWidget (shell);
  682.     }
  683.   else
  684.     {
  685.       dcache_is_visible = 1;
  686.  
  687.       shell = XtCreatePopupShell ("SPIM Data Cache", topLevelShellWidgetClass,
  688.                   toplevel_cache, NULL, ZERO);
  689.       pane = XtCreateManagedWidget ("Pane", panedWidgetClass, shell,
  690.                     NULL, ZERO);
  691.  
  692.       n = 0;
  693.       XtSetArg (args[n], XtNtype, XawAsciiString); n++;
  694.       XtSetArg (args[n], XtNeditType, XawtextRead); n++;
  695.       XtSetArg (args[n], XtNpreferredPaneSize, TEXTHEIGHT * 3); n++;
  696.       XtSetArg (args[n], XtNwidth, TEXTWIDTH*35); n++;
  697.       XtSetArg (args[n], XtNstring, ""); n++;
  698.       XtSetArg (args[n], XtNborderWidth, 0); n++;
  699.       XtSetArg (args[n], XtNdisplayCaret, False); n++;
  700.       dcache_stats = XtCreateManagedWidget ("dcache_stats",
  701.                         asciiTextWidgetClass,pane,args,n);
  702.  
  703.       n = 0;
  704.       XtSetArg (args[n], XtNtype, XawAsciiString); n++;
  705.       XtSetArg (args[n], XtNeditType, XawtextRead); n++;
  706.       XtSetArg (args[n], XtNscrollVertical, XawtextScrollWhenNeeded); n++;
  707.       XtSetArg (args[n], XtNpreferredPaneSize, TEXTHEIGHT * 15); n++;
  708.       XtSetArg (args[n], XtNwidth, TEXTWIDTH*35); n++;
  709.       XtSetArg (args[n], XtNstring, ""); n++;
  710.       XtSetArg (args[n], XtNborderWidth, 0); n++;
  711.       XtSetArg (args[n], XtNdisplayCaret, False); n++;
  712.       dcache_data = XtCreateManagedWidget ("dcache_data",
  713.                        asciiTextWidgetClass,pane,args,n);
  714.       XtPopup (shell, XtGrabNone);
  715.  
  716.       dcache_modified = 1;
  717.       display_cache (dcache_stats, dcache_data, DATA_CACHE);
  718.     }
  719. }
  720.  
  721.  
  722. #ifdef __STDC__
  723. void
  724. pop_icache (Widget w, XtPointer client_data, XtPointer call_data)
  725. #else
  726. void
  727. pop_icache (w, client_data, call_data)
  728.      Widget w;
  729.      XtPointer client_data, call_data;
  730. #endif
  731. {
  732.   static Widget shell = NULL;
  733.   Widget pane;
  734.   Arg args[10];
  735.   int n;
  736.  
  737.   if (icache_is_visible)
  738.     {
  739.       icache_is_visible = 0;
  740.       XtDestroyWidget (shell);
  741.     }
  742.   else
  743.     {
  744.       icache_is_visible = 1;
  745.  
  746.       shell = XtCreatePopupShell ("SPIM Instruction Cache",
  747.                   topLevelShellWidgetClass, toplevel_cache,
  748.                   NULL, ZERO);
  749.       pane = XtCreateManagedWidget ("Pane", panedWidgetClass, shell,
  750.                     NULL, ZERO);
  751.  
  752.       n = 0;
  753.       XtSetArg (args[n], XtNtype, XawAsciiString); n++;
  754.       XtSetArg (args[n], XtNeditType, XawtextRead); n++;
  755.       XtSetArg (args[n], XtNpreferredPaneSize, TEXTHEIGHT * 3); n++;
  756.       XtSetArg (args[n], XtNwidth, TEXTWIDTH*35); n++;
  757.       XtSetArg (args[n], XtNstring, ""); n++;
  758.       XtSetArg (args[n], XtNborderWidth, 0); n++;
  759.       XtSetArg (args[n], XtNdisplayCaret, False); n++;
  760.       icache_stats = XtCreateManagedWidget ("icache_stats",
  761.                         asciiTextWidgetClass,pane,args,n);
  762.  
  763.       n = 0;
  764.       XtSetArg (args[n], XtNtype, XawAsciiString); n++;
  765.       XtSetArg (args[n], XtNeditType, XawtextRead); n++;
  766.       XtSetArg (args[n], XtNscrollVertical, XawtextScrollWhenNeeded); n++;
  767.       XtSetArg (args[n], XtNpreferredPaneSize, TEXTHEIGHT * 15); n++;
  768.       XtSetArg (args[n], XtNwidth, TEXTWIDTH*35); n++;
  769.       XtSetArg (args[n], XtNstring, ""); n++;
  770.       XtSetArg (args[n], XtNborderWidth, 0); n++;
  771.       XtSetArg (args[n], XtNdisplayCaret, False); n++;
  772.       icache_data = XtCreateManagedWidget ("icache_data",
  773.                        asciiTextWidgetClass,pane,args,n);
  774.       XtPopup (shell, XtGrabNone);
  775.  
  776.       icache_modified = 1;
  777.       display_cache (icache_stats, icache_data, INST_CACHE);
  778.     }
  779. }
  780. #endif
  781.  
  782.  
  783. #ifdef __STDC__
  784. void
  785. read_file (char *name, int assembly_file)
  786. #else
  787. void
  788. read_file (name, assembly_file)
  789.      char *name;
  790.      int assembly_file;
  791. #endif
  792. {
  793.   int error_flag;
  794.  
  795.   if (*name == '\0')
  796.     error_flag = 1;
  797.   else if (assembly_file)
  798.     error_flag = read_assembly_file (name);
  799. #ifdef mips
  800.   else
  801.     {
  802.       initialize_world (0);
  803. #ifdef CL_SPIM
  804.       cl_initialize_world (0);
  805. #endif
  806.  
  807.       error_flag = read_aout_file (name);
  808.     }
  809. #endif
  810.   if (!error_flag)
  811.     {
  812.       redisplay_text ();
  813.       redisplay_data ();
  814.     }
  815. }
  816.  
  817.  
  818. #ifdef __STDC__
  819. void
  820. start_program (mem_addr addr)
  821. #else
  822. void
  823. start_program (addr)
  824.      mem_addr addr;
  825. #endif
  826. {
  827.   if (addr == 0)
  828.     addr = starting_address ();
  829.  
  830.   if (addr != 0)
  831.     execute_program (addr, DEFAULT_RUN_STEPS, 0, 0);
  832. }
  833.  
  834.  
  835. #ifdef __STDC__
  836. void
  837. execute_program (mem_addr pc, int steps, int display, int cont_bkpt)
  838. #else
  839. void
  840. execute_program (pc, steps, display, cont_bkpt)
  841.      mem_addr pc;
  842.      int steps, display, cont_bkpt;
  843. #endif
  844. {
  845.   if (!setjmp (spim_top_level_env))
  846.     {
  847.       spim_is_running = 1;
  848.       show_running ();
  849. #ifdef CL_SPIM
  850.       if (cycle_level == 1)
  851.     {
  852.       cl_run_program (pc, steps, 0 /*display*/);
  853.     }
  854.       else
  855. #endif
  856.       if (run_program (pc, steps, display, cont_bkpt))
  857.     continue_prompt (0);
  858.     }
  859.   spim_is_running = 0;
  860.   center_text_at_PC ();
  861.   redisplay_data ();
  862. }
  863.  
  864.  
  865. #ifdef __STDC__
  866. static void
  867. show_running (void)
  868. #else
  869. static void
  870. show_running ()
  871. #endif
  872. {
  873.   Arg args[1];
  874.  
  875.   XtSetArg (args[0], XtNstring, "Running.....");
  876.   XtSetValues (register_window, args, ONE);
  877. }
  878.  
  879.  
  880. /* Redisplay the contents of the registers and, if modified, the data
  881.    and stack segments. */
  882.  
  883. #ifdef __STDC__
  884. void
  885. redisplay_data (void)
  886. #else
  887. void
  888. redisplay_data ()
  889. #endif
  890. {
  891.   display_registers ();
  892.   display_data_seg ();
  893. #ifdef CL_SPIM
  894.   if (pipeline_is_visible) display_pipeline ();
  895.   if (dcache_is_visible)
  896.     display_cache (dcache_stats, dcache_data, DATA_CACHE);
  897.   if (icache_is_visible)
  898.     display_cache (icache_stats, icache_data, INST_CACHE);
  899. #endif
  900. }
  901.  
  902.  
  903. /* Redisplay the contents of the registers in a wide variety of
  904.    formats. */
  905.  
  906. #ifdef __STDC__
  907. static void
  908. display_registers (void)
  909. #else
  910. static void
  911. display_registers ()
  912. #endif
  913. {
  914.   int i;
  915.   static String buf;
  916.   String bufp;
  917.   char *grstr, *fpstr;
  918.   char *grfill, *fpfill;
  919.   Arg args [2];
  920.   static char *reg_names[] = {"r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
  921.                   "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
  922.                   "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
  923.                   "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"};
  924.  
  925.   if (buf == NULL)
  926.     buf = (String) malloc (8 * K);
  927.   *buf = '\0';
  928.   bufp = buf;
  929.  
  930.   sprintf (bufp, " PC     = %08x    ", PC); bufp += strlen (bufp);
  931.   sprintf (bufp, " EPC    = %08x    ", EPC); bufp += strlen (bufp);
  932.   sprintf (bufp, " Cause  = %08x    ", Cause); bufp += strlen (bufp);
  933.   sprintf (bufp, " BadVAddr= %08x\n", BadVAddr); bufp += strlen (bufp);
  934.   sprintf (bufp, " Status = %08x    ", Status_Reg); bufp += strlen (bufp);
  935.   sprintf (bufp, " HI     = %08x    ", HI); bufp += strlen (bufp);
  936.   sprintf (bufp, " LO     = %08x\n", LO); bufp += strlen (bufp);
  937.  
  938.   if (print_gpr_hex)
  939.     grstr = "R%-2d (%2s) = %08x", grfill = "  ";
  940.   else
  941.     grstr = "R%-2d (%2s) = %-10d", grfill = " ";
  942.   sprintf (bufp, "\t\t\t\t General Registers\n"); bufp += strlen (bufp);
  943.   for (i = 0; i < 8; i++)
  944.     {
  945.       sprintf (bufp, grstr, i, reg_names[i], R[i]);
  946.       bufp += strlen (bufp);
  947.       sprintf (bufp, grfill); bufp += strlen (bufp);
  948.       sprintf (bufp, grstr, i+8, reg_names[i+8], R[i+8]);
  949.       bufp += strlen (bufp);
  950.       sprintf (bufp, grfill); bufp += strlen (bufp);
  951.       sprintf (bufp, grstr, i+16, reg_names[i+16], R[i+16]);
  952.       bufp += strlen (bufp);
  953.       sprintf (bufp, grfill); bufp += strlen (bufp);
  954.       sprintf (bufp, grstr, i+24, reg_names[i+24], R[i+24]);
  955.       bufp += strlen (bufp);
  956.       sprintf (bufp, "\n");
  957.       bufp += 1;
  958.     }
  959.  
  960.   if (print_fpr_hex)
  961.     fpstr = "FP%-2d=%08x,%08x", fpfill = " ";
  962.   else
  963.     fpstr = "FP%-2d = %-10.4f", fpfill = "  ";
  964.   sprintf (bufp, "\t\t\t      Double Floating Point Registers\n");
  965.   bufp += strlen (bufp);
  966.   if (print_fpr_hex)
  967.     for (i = 0; i < 4; i += 1)
  968.       {
  969.     int *r1, *r2;
  970.  
  971.     /* Use pointers to cast to ints without invoking float->int conversion
  972.        so we can just print the bits. */
  973.     r1 = (int *)&FGR[i]; r2 = (int *)&FGR[i+1];
  974.     sprintf (bufp, fpstr, 2*i, *r1, *r2); bufp += strlen (bufp);
  975.     sprintf (bufp, fpfill); bufp += strlen (bufp);
  976.  
  977.     r1 = (int *)&FGR[i+4]; r2 = (int *)&FGR[i+4+1];
  978.     sprintf (bufp, fpstr, 2*i+8, *r1, *r2); bufp += strlen (bufp);
  979.     sprintf (bufp, fpfill); bufp += strlen (bufp);
  980.  
  981.     r1 = (int *)&FGR[i+8]; r2 = (int *)&FGR[i+8+1];
  982.     sprintf (bufp, fpstr, 2*i+16, *r1, *r2); bufp += strlen (bufp);
  983.     sprintf (bufp, fpfill); bufp += strlen (bufp);
  984.  
  985.     r1 = (int *)&FGR[i+12]; r2 = (int *)&FGR[i+12+1];
  986.     sprintf (bufp, fpstr, 2*i+24, *r1, *r2); bufp += strlen (bufp);
  987.     sprintf (bufp, "\n"); bufp += 1;
  988.       }
  989.   else for (i = 0; i < 4; i += 1)
  990.     {
  991.       sprintf (bufp, fpstr, 2*i, FPR[i]);
  992.       bufp += strlen (bufp);
  993.       sprintf (bufp, fpfill); bufp += strlen (bufp);
  994.       sprintf (bufp, fpstr, 2*i+8, FPR[i+4]);
  995.       bufp += strlen (bufp);
  996.       sprintf (bufp, fpfill); bufp += strlen (bufp);
  997.       sprintf (bufp, fpstr, 2*i+16, FPR[i+8]);
  998.       bufp += strlen (bufp);
  999.       sprintf (bufp, fpfill); bufp += strlen (bufp);
  1000.       sprintf (bufp, fpstr, 2*i+24, FPR[i+12]);
  1001.       bufp += strlen (bufp);
  1002.       sprintf (bufp, "\n");
  1003.       bufp += 1;
  1004.     }
  1005.  
  1006.   if (print_fpr_hex)
  1007.     fpstr = "FP%-2d=%08x", fpfill = " ";
  1008.   else
  1009.     fpstr = "FP%-2d = %-10.4f", fpfill = "  ";
  1010.   sprintf (bufp, "\t\t\t      Single Floating Point Registers\n");
  1011.   bufp += strlen (bufp);
  1012.   if (print_fpr_hex)
  1013.     for (i = 0; i < 4; i += 1)
  1014.       {
  1015.     int *r1;
  1016.  
  1017.     /* Use pointers to cast to ints without invoking float->int conversion
  1018.        so we can just print the bits. */
  1019.     r1 = (int *)&FGR[i];
  1020.     sprintf (bufp, fpstr, 2*i, *r1); bufp += strlen (bufp);
  1021.     sprintf (bufp, fpfill); bufp += strlen (bufp);
  1022.  
  1023.     r1 = (int *)&FGR[i+4];
  1024.     sprintf (bufp, fpstr, 2*i+8, *r1); bufp += strlen (bufp);
  1025.     sprintf (bufp, fpfill); bufp += strlen (bufp);
  1026.  
  1027.     r1 = (int *)&FGR[i+8];
  1028.     sprintf (bufp, fpstr, 2*i+16, *r1); bufp += strlen (bufp);
  1029.     sprintf (bufp, fpfill); bufp += strlen (bufp);
  1030.  
  1031.     r1 = (int *)&FGR[i+12];
  1032.     sprintf (bufp, fpstr, 2*i+24, *r1); bufp += strlen (bufp);
  1033.     sprintf (bufp, "\n"); bufp += 1;
  1034.       }
  1035.   else for (i = 0; i < 4; i += 1)
  1036.     {
  1037.       sprintf (bufp, fpstr, 2*i, FGR[2*i]);
  1038.       bufp += strlen (bufp);
  1039.       sprintf (bufp, fpfill); bufp += strlen (bufp);
  1040.       sprintf (bufp, fpstr, 2*(i+4), FGR[2*(i+4)]);
  1041.       bufp += strlen (bufp);
  1042.       sprintf (bufp, fpfill); bufp += strlen (bufp);
  1043.       sprintf (bufp, fpstr, 2*(i+8), FGR[2*(i+8)]);
  1044.       bufp += strlen (bufp);
  1045.       sprintf (bufp, fpfill); bufp += strlen (bufp);
  1046.       sprintf (bufp, fpstr, 2*(i+12), FGR[2*(i+12)]);
  1047.       bufp += strlen (bufp);
  1048.       sprintf (bufp, "\n");
  1049.       bufp += 1;
  1050.     }
  1051.   XtSetArg (args[0], XtNstring, buf);
  1052.   XtSetArg (args[1], XtNlength, bufp - buf);
  1053.   XtSetValues (register_window, args, TWO);
  1054. }
  1055.  
  1056.  
  1057. /* Redisplay the text segment and ktext segments. */
  1058.  
  1059. #ifdef __STDC__
  1060. void
  1061. redisplay_text (void)
  1062. #else
  1063. void
  1064. redisplay_text ()
  1065. #endif
  1066. {
  1067.   static String buf;
  1068.   int limit, n;
  1069.   Arg args [2];
  1070.  
  1071.   if (!text_modified)
  1072.     return;
  1073.   if (buf == NULL)
  1074.     buf = (String) malloc (16*K);
  1075.   *buf = '\0';
  1076.   limit = 16*K;
  1077.   n = 0;
  1078.   buf = display_insts (TEXT_BOT, text_top, buf, &limit, &n);
  1079.   sprintf (&buf[n], "\n\tKERNEL\n");
  1080.   n += strlen (&buf[n]);
  1081.   buf = display_insts (K_TEXT_BOT, k_text_top, buf, &limit, &n);
  1082.  
  1083.   XtSetArg (args[0], XtNstring, buf);
  1084.   XtSetArg (args[1], XtNlength, limit);
  1085.   XtSetValues (text_window, args, TWO);
  1086.   text_modified = 0;
  1087. }
  1088.  
  1089.  
  1090. /* Write a printable representation of the instructions in memory
  1091.    address FROM...TO to buffer BUF, which is of size LIMIT and whose next
  1092.    free location is N.  Return the, possible realloc'ed, buffer. */
  1093.  
  1094. #ifdef __STDC__
  1095. static char *
  1096. display_insts (mem_addr from, mem_addr to, char *buf, int *limit, int *n)
  1097. #else
  1098. static char *
  1099. display_insts (from, to, buf, limit, n)
  1100.      mem_addr from, to;
  1101.      char *buf;
  1102.      int *limit, *n;
  1103. #endif
  1104. {
  1105.   instruction *inst;
  1106.   mem_addr i;
  1107.  
  1108.   for (i = from; i < to; i += 4)
  1109.     {
  1110.       READ_MEM_INST (inst, i);
  1111.       if (inst != NULL)
  1112.     {
  1113.       *n += print_inst_internal (&buf[*n], 1*K, inst, i);
  1114.       if ((*limit - *n) < 1*K)
  1115.         {
  1116.           *limit = 2 * *limit;
  1117.           if ((buf = (char *) realloc (buf, *limit)) == 0)
  1118.         fatal_error ("realloc failed\n");
  1119.         }
  1120.     }
  1121.     }
  1122.   return (buf);
  1123. }
  1124.  
  1125.  
  1126. /* Center the text window at the instruction at the current PC and
  1127.    highlight the instruction. */
  1128.  
  1129. #ifdef __STDC__
  1130. static void
  1131. center_text_at_PC (void)
  1132. #else
  1133. static void
  1134. center_text_at_PC ()
  1135. #endif
  1136. {
  1137.   char buf[100];
  1138.   XawTextBlock text;
  1139.   XawTextPosition start, finish;
  1140.   static mem_addr prev_PC = 0;
  1141.   XRectangle cursor_loc;
  1142.   Arg args[10];
  1143.   static Widget text_window_sink = 0;
  1144.   static int highlight_x = -1, highlight_y;
  1145.   static XawTextPosition highlight_start, highlight_finish;
  1146.  
  1147.   if (text_window_sink == 0)
  1148.     {
  1149.       XtSetArg (args[0], XtNtextSink, &text_window_sink);
  1150.       XtGetValues (text_window, args, ONE);
  1151.     }
  1152.  
  1153.   if (highlight_x != -1)
  1154.     {
  1155.       XawTextSinkDisplayText (text_window_sink,
  1156.                   highlight_x, highlight_y,
  1157.                   highlight_start, highlight_finish, 0);
  1158.       highlight_x = -1;
  1159.     }
  1160.  
  1161.   if (PC < TEXT_BOT || (PC > text_top && (PC < K_TEXT_BOT || PC > k_text_top)))
  1162.     return;
  1163.  
  1164.   sprintf (buf, "\n[0x%08x]", PC);
  1165.   text.firstPos = 0;
  1166.   text.length = strlen (buf);
  1167.   text.ptr = buf;
  1168.   text.format = FMT8BIT;
  1169.  
  1170.   /* Find start of line at PC: */
  1171.   start = XawTextSearch (text_window, prev_PC <= PC ? XawsdRight : XawsdLeft,
  1172.              &text);
  1173.   if (start == XawTextSearchError)
  1174.     return;
  1175.  
  1176.   XawTextSetInsertionPoint (text_window, start);
  1177.  
  1178.   /* Find start of following line: */
  1179.   sprintf (buf, "\n[0x%08x]", PC + BYTES_PER_WORD);
  1180.   finish = XawTextSearch (text_window, XawsdRight, &text);
  1181.   if (finish == XawTextSearchError)
  1182.     return;
  1183.  
  1184.   /* Find PC line's location in the window: */
  1185.   XawTextSetInsertionPoint (text_window, start + 1);
  1186.   XawTextSinkGetCursorBounds (text_window_sink, &cursor_loc);
  1187.   highlight_x = cursor_loc.x + cursor_loc.width/2;
  1188.   XawTextSetInsertionPoint (text_window, start);
  1189.   XawTextSinkGetCursorBounds (text_window_sink, &cursor_loc);
  1190.   highlight_y = cursor_loc.y + cursor_loc.height;
  1191.   highlight_start = start;
  1192.   highlight_finish = finish;
  1193.  
  1194.  
  1195.   /* Highlight the line: */
  1196.   XawTextSinkDisplayText (text_window_sink,
  1197.               highlight_x, highlight_y,
  1198.               highlight_start, highlight_finish, 1);
  1199.  
  1200.   XawTextSetInsertionPoint (text_window, start);
  1201.   prev_PC = PC;
  1202. }
  1203.  
  1204.  
  1205. /* Display the contents of the data and stack segments, if they have
  1206.    been modified. */
  1207.  
  1208. #ifdef __STDC__
  1209. static void
  1210. display_data_seg (void)
  1211. #else
  1212. static void
  1213. display_data_seg ()
  1214. #endif
  1215. {
  1216.   static String buf;
  1217.   int limit, n;
  1218.   Arg args [2];
  1219.  
  1220.   if (!data_modified)
  1221.     return;
  1222.  
  1223.   if (buf == NULL)
  1224.     buf = (String) malloc (16*K);
  1225.   *buf = '\0';
  1226.   limit = 16*K;
  1227.   n = 0;
  1228.  
  1229.   sprintf (&buf[n], "\n\tDATA\n");
  1230.   n += strlen (&buf[n]);
  1231.   buf = display_values (DATA_BOT, data_top, buf, &limit, &n);
  1232.   sprintf (&buf[n], "\n\tSTACK\n");
  1233.   n += strlen (&buf[n]);
  1234.   buf = display_values (R[29],
  1235.             STACK_TOP - 4096,
  1236.             buf,
  1237.             &limit,
  1238.             &n);
  1239.   sprintf (&buf[n], "\n\tKERNEL DATA\n");
  1240.   n += strlen (&buf[n]);
  1241.   buf = display_values (K_DATA_BOT, k_data_top, buf, &limit, &n);
  1242.  
  1243.   XtSetArg (args[0], XtNstring, buf);
  1244.   XtSetArg (args[1], XtNlength, limit);
  1245.   XtSetValues (data_window, args, TWO);
  1246.   data_modified = 0;
  1247. }
  1248.  
  1249.  
  1250. #ifdef CL_SPIM
  1251. #ifdef __STDC__
  1252. static void
  1253. display_pipeline (void)
  1254. #else
  1255. static void
  1256. display_pipeline ()
  1257. #endif
  1258. {
  1259.   char *buf;
  1260.   int limit;
  1261.   Arg args [2];
  1262.  
  1263.   buf = (char *) malloc (8*K);
  1264.   *buf = '\0';
  1265.   limit = 8*K;
  1266.  
  1267.   print_pipeline_internal (buf);
  1268.   XtSetArg (args[0], XtNstring, buf);
  1269.   XtSetArg (args[1], XtNlength, limit);
  1270.   XtSetValues (pipeline, args, TWO);
  1271. }
  1272.  
  1273.  
  1274. #ifdef __STDC__
  1275. static void
  1276. display_cache (Widget stats, Widget data, int type)
  1277. #else
  1278. static void
  1279. display_cache (stats, data, type)
  1280. Widget stats, data;
  1281. #endif
  1282. {
  1283.   char *buf;
  1284.   int limit;
  1285.   Arg args [3];
  1286.  
  1287.   switch (type)
  1288.     {
  1289.     case DATA_CACHE:
  1290.       if (!dcache_modified) return;
  1291.       dcache_modified = 0;
  1292.       break;
  1293.     case INST_CACHE:
  1294.       if (!icache_modified) return;
  1295.       icache_modified = 0;
  1296.       break;
  1297.     }
  1298.  
  1299.   if (! (buf = (char *) malloc (16*K)))
  1300.     {
  1301.       error ("Bad malloc on cache update.\n");
  1302.       return;
  1303.     }
  1304.   limit = 16*K;
  1305.  
  1306.   *buf = '\0';
  1307.   print_cache_stats (buf, type);
  1308.   XtSetArg (args[0], XtNstring, buf);
  1309.   XtSetArg (args[1], XtNlength, limit);
  1310.   XtSetValues (stats, args, TWO);
  1311.  
  1312.   *buf = '\0';
  1313.   print_cache_data (buf, type);
  1314.   XtSetArg (args[0], XtNstring, buf);
  1315.   XtSetArg (args[1], XtNlength, limit);
  1316.   XtSetValues (data, args, TWO);
  1317. }
  1318. #endif
  1319.  
  1320.  
  1321. #define BYTES_PER_LINE (4*BYTES_PER_WORD)
  1322.  
  1323.  
  1324. /* Write a printable representation of the data in memory address
  1325.    FROM...TO to buffer BUF, which is of size LIMIT and whose next free
  1326.    location is N.  Return the, possible realloc'ed, buffer. */
  1327.  
  1328. #ifdef __STDC__
  1329. static char *
  1330. display_values (mem_addr from, mem_addr to, char *buf, int *limit, int *n)
  1331. #else
  1332. static char *
  1333. display_values (from, to, buf, limit, n)
  1334.      mem_addr from, to;
  1335.      char *buf;
  1336.      int *limit, *n;
  1337. #endif
  1338. {
  1339.   mem_word val;
  1340.   mem_addr i = ROUND (from, BYTES_PER_WORD);
  1341.   int j;
  1342.  
  1343.   i = print_partial_line (i, buf, limit, n);
  1344.  
  1345.   for ( ; i < to; )
  1346.     {
  1347.       /* Look for a block of 4 or more zero memory words */
  1348.       for (j = 0; i + j < to; j += BYTES_PER_WORD)
  1349.     {
  1350.       READ_MEM_WORD (val, i + j);
  1351.       if (val != 0)
  1352.         break;
  1353.     }
  1354.       if (i + j < to)
  1355.     j -= BYTES_PER_WORD;
  1356.  
  1357.       if (j >= 4 * BYTES_PER_WORD)
  1358.     {
  1359.       sprintf (&buf[*n], "[0x%08x]...[0x%08x]    0x00000000\n",
  1360.            i, i + j);
  1361.       buf = check_buf_limit (buf, limit, n);
  1362.       i = i + j;
  1363.  
  1364.       i = print_partial_line (i, buf, limit, n);
  1365.     }
  1366.       else
  1367.     {
  1368.       /* Otherwise, print the next four words on a single line */
  1369.       sprintf (&buf[*n], "[0x%08x]              ", i);
  1370.       *n += strlen (&buf[*n]);
  1371.       do
  1372.         {
  1373.           READ_MEM_WORD (val, i);
  1374.           sprintf (&buf[*n], "  0x%08x", val);
  1375.           *n += strlen (&buf[*n]);
  1376.           i += BYTES_PER_WORD;
  1377.         }
  1378.       while (i % BYTES_PER_LINE != 0);
  1379.       sprintf (&buf[*n], "\n");
  1380.       buf = check_buf_limit (buf, limit, n);
  1381.     }
  1382.     }
  1383.   return (buf);
  1384. }
  1385.  
  1386.  
  1387.  
  1388. /* Check to see if the buffer is getting too full and, if so,
  1389.    reallocate it. */
  1390.  
  1391. #ifdef __STDC__
  1392. static char *
  1393. check_buf_limit (char *buf, int *limit, int *n)
  1394. #else
  1395. static char *
  1396. check_buf_limit (buf, limit, n)
  1397.      char *buf;
  1398.      int *limit, *n;
  1399. #endif
  1400. {
  1401.   *n += strlen (&buf[*n]);
  1402.   if ((*limit - *n) < 1*K)
  1403.     {
  1404.       *limit = 2 * *limit;
  1405.       if ((buf = (char *) realloc (buf, *limit)) == 0)
  1406.     fatal_error ("realloc failed\n");
  1407.     }
  1408.   return (buf);
  1409. }
  1410.  
  1411.  
  1412.  
  1413. /* Print out a line containing a fraction of a quadword.  */
  1414.  
  1415. #ifdef __STDC__
  1416. static mem_addr
  1417. print_partial_line (mem_addr i, char *buf, int *limit, int *n)
  1418. #else
  1419. static mem_addr
  1420. print_partial_line (i, buf, limit, n)
  1421.      mem_addr i;
  1422.      char *buf;
  1423.      int *limit, *n;
  1424. #endif
  1425. {
  1426.   mem_word val;
  1427.  
  1428.   if ((i % BYTES_PER_LINE) != 0)
  1429.     {
  1430.       sprintf (&buf[*n], "[0x%08x]              ", i);
  1431.       buf = check_buf_limit (buf, limit, n);
  1432.  
  1433.       for (; (i % BYTES_PER_LINE) != 0; i += BYTES_PER_WORD)
  1434.     {
  1435.       READ_MEM_WORD (val, i);
  1436.       sprintf (&buf[*n], "  0x%08x", val);
  1437.       buf = check_buf_limit (buf, limit, n);
  1438.     }
  1439.  
  1440.       sprintf (&buf[*n], "\n");
  1441.       buf = check_buf_limit (buf, limit, n);
  1442.     }
  1443.  
  1444.   return (i);
  1445. }
  1446.  
  1447.  
  1448.  
  1449.  
  1450. /* IO facilities: */
  1451.  
  1452.  
  1453. #ifdef __STDC__
  1454. void
  1455. write_output (long fp, char *fmt, ...)
  1456. #else
  1457. /*VARARGS0*/
  1458. void
  1459. write_output (va_alist)
  1460. va_dcl
  1461. #endif
  1462. {
  1463.   va_list args;
  1464.   Widget w;
  1465. #ifndef __STDC__
  1466.   char *fmt;
  1467.   long fp;
  1468. #endif
  1469.   char io_buffer [IO_BUFFSIZE];
  1470.  
  1471. #ifdef __STDC__
  1472.   va_start (args, fmt);
  1473. #else
  1474.   va_start (args);
  1475.   fp = va_arg (args, long);
  1476.   fmt = va_arg (args, char *);
  1477. #endif
  1478.   w = (Widget) fp;        /* Not too portable... */
  1479.  
  1480.   if (w == console && !console_is_visible)
  1481.     {
  1482.       XtPopup (shell1, XtGrabNone);
  1483.       console_is_visible = 1;
  1484.     }
  1485.  
  1486.   vsprintf (io_buffer, fmt, args);
  1487.   va_end (args);
  1488.  
  1489.   write_text_to_window (w, io_buffer);
  1490.  
  1491.   /* Look for keyboard input (such as ^C) */
  1492.   while (XtAppPending (app_context))
  1493.     {
  1494.       XEvent event;
  1495.  
  1496.       XtAppNextEvent (app_context, &event);
  1497.       XtDispatchEvent (&event);
  1498.     }
  1499. }
  1500.  
  1501.  
  1502. /* Simulate the semantics of fgets, not gets, on an x-window. */
  1503.  
  1504. #ifdef __STDC__
  1505. void
  1506. read_input (char *str, int str_size)
  1507. #else
  1508. void
  1509. read_input (str, str_size)
  1510.      char *str;
  1511.      int str_size;
  1512. #endif
  1513. {
  1514.   char buffer[11];
  1515.   KeySym key;
  1516.   XComposeStatus compose;
  1517.   XEvent event;
  1518.   char *ptr;
  1519.  
  1520.   ptr = str;
  1521.   str_size -= 1;        /* Reserve space for null */
  1522.  
  1523.   if (!console_is_visible)
  1524.     {
  1525.       XtPopup (shell1, XtGrabNone);
  1526.       console_is_visible = 1;
  1527.     }
  1528.  
  1529.   while (1)
  1530.     {
  1531.       XtAppNextEvent (app_context, &event);
  1532.       if (event.type == KeyPress)
  1533.     {
  1534.       int chars = XLookupString (&event.xkey, buffer, 10, &key, &compose);
  1535.       if ((key == XK_Return) || (key == XK_KP_Enter))
  1536.         {
  1537.           *ptr++ = '\n';
  1538.           *ptr = '\0';
  1539.           write_text_to_window (console, "\n");
  1540.           return;
  1541.         }
  1542.       else if (*buffer == 3) /* ^C */
  1543.         XtDispatchEvent (&event);
  1544.       else
  1545.         {
  1546.           int n = (chars < str_size ? chars : str_size);
  1547.  
  1548.           strncpy (ptr, buffer, n);
  1549.           ptr += n;
  1550.           *ptr = '\0';
  1551.           str_size -= n;
  1552.           buffer[chars] = '\0';
  1553.           write_text_to_window (console, buffer);
  1554.           if (str_size == 0)
  1555.         return;
  1556.         }
  1557.     }
  1558.       else
  1559.     XtDispatchEvent (&event);
  1560.     }
  1561. }
  1562.  
  1563.  
  1564. #ifdef __STDC__
  1565. int
  1566. console_input_available (void)
  1567. #else
  1568. int
  1569. console_input_available ()
  1570. #endif
  1571. {
  1572.   if (mapped_io)
  1573.     return (XtAppPending (app_context));
  1574.   else
  1575.     return (0);
  1576. }
  1577.  
  1578.  
  1579. #ifdef __STDC__
  1580. char
  1581. get_console_char (void)
  1582. #else
  1583. char
  1584. get_console_char ()
  1585. #endif
  1586. {
  1587.   XEvent event;
  1588.  
  1589.   if (!console_is_visible)
  1590.     {
  1591.       XtPopup (shell1, XtGrabNone);
  1592.       console_is_visible = 1;
  1593.     }
  1594.  
  1595.   while (1)
  1596.     {
  1597.       XtAppNextEvent (app_context, &event);
  1598.       if (event.type == KeyPress)
  1599.     {
  1600.       char buffer[11];
  1601.       KeySym key;
  1602.       XComposeStatus compose;
  1603.       XLookupString (&event.xkey, buffer, 10, &key, &compose);
  1604.  
  1605.       if (*buffer == 3)               /* ^C */
  1606.         XtDispatchEvent (&event);
  1607.       else if (*buffer != 0)
  1608.         return (buffer[0]);
  1609.     }
  1610.       else
  1611.     XtDispatchEvent (&event);
  1612.     }
  1613. }
  1614.  
  1615.  
  1616. #ifdef __STDC__
  1617. void
  1618. put_console_char (char c)
  1619. #else
  1620. void
  1621. put_console_char (c)
  1622.      char c;
  1623. #endif
  1624. {
  1625.   char buf[4];
  1626.  
  1627.   buf[0] = c;
  1628.   buf[1] = '\0';
  1629.   if (!console_is_visible)
  1630.     {
  1631.       XtPopup (shell1, XtGrabNone);
  1632.       console_is_visible = 1;
  1633.     }
  1634.   write_text_to_window (console, buf);
  1635. }
  1636.  
  1637.  
  1638.  
  1639. /* Print an error message. */
  1640.  
  1641. #ifdef __STDC__
  1642. void
  1643. error (char *fmt, ...)
  1644. #else
  1645. /*VARARGS0*/
  1646. void
  1647. error (va_alist)
  1648. va_dcl
  1649. #endif
  1650. {
  1651.   va_list args;
  1652. #ifndef __STDC__
  1653.   char *fmt;
  1654. #endif
  1655.   char io_buffer [IO_BUFFSIZE];
  1656.  
  1657. #ifdef __STDC__
  1658.   va_start (args, fmt);
  1659. #else
  1660.   va_start (args);
  1661.   fmt = va_arg (args, char *);
  1662. #endif
  1663.   vsprintf (io_buffer, fmt, args);
  1664.   va_end (args);
  1665.   if (message != 0)
  1666.     write_text_to_window (message, io_buffer);
  1667.   else
  1668.     fprintf (stderr, "%s", io_buffer);
  1669. }
  1670.  
  1671.  
  1672. #ifdef __STDC__
  1673. int
  1674. run_error (char *fmt, ...)
  1675. #else
  1676. /*VARARGS0*/
  1677. int
  1678. run_error (va_alist)
  1679. va_dcl
  1680. #endif
  1681. {
  1682.   va_list args;
  1683. #ifndef __STDC__
  1684.   char *fmt;
  1685. #endif
  1686.   char io_buffer [IO_BUFFSIZE];
  1687.  
  1688. #ifdef __STDC__
  1689.   va_start (args, fmt);
  1690. #else
  1691.   va_start (args);
  1692.   fmt = va_arg (args, char *);
  1693. #endif
  1694.   vsprintf (io_buffer, fmt, args);
  1695.   va_end (args);
  1696.   if (message != 0)
  1697.     write_text_to_window (message, io_buffer);
  1698.   else
  1699.     fprintf (stderr, "%s", io_buffer);
  1700.   if (spim_is_running)
  1701.     longjmp (spim_top_level_env, 1);
  1702.   return (0);            /* So it can be used in expressions */
  1703. }
  1704.  
  1705.  
  1706. #ifdef __STDC__
  1707. static void
  1708. write_text_to_window (Widget w, char *s)
  1709. #else
  1710. static void
  1711. write_text_to_window (w, s)
  1712.      Widget w;
  1713.      char *s;
  1714. #endif
  1715. {
  1716.   XawTextBlock textblock;
  1717.   XawTextPosition ip = XawTextGetInsertionPoint (w);
  1718.  
  1719.   if (!s || strlen (s) == 0) return;
  1720.  
  1721.   textblock.firstPos = 0;
  1722.   textblock.length = strlen (s);
  1723.   textblock.ptr = s;
  1724.   textblock.format = FMT8BIT;
  1725.  
  1726.   XawTextReplace (w, ip, ip, &textblock);
  1727.   XawTextSetInsertionPoint (w,
  1728.                 XawTextGetInsertionPoint (w) + textblock.length);
  1729. }
  1730.